package com.ztr.conversion.html2word;

import com.aspose.words.Document;
import com.aspose.words.DocumentBuilder;
import com.aspose.words.SaveFormat;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;

/**
 * <p>
 * Html 转 Word 工具类
 * </p>
 */
@Slf4j
public class Htm2WordUtil {


    /**
     * 将HTML字节序列转换为Word字节序列。
     * 该方法通过解析HTML内容并将其保存为DOCX格式来实现转换。
     * 使用Apache POI库处理Microsoft Word文档。
     *
     * @param htmlBytes HTML内容的字节序列。
     * @return DOCX格式的字节序列。
     * @throws Exception 如果在处理HTML或保存DOCX时发生错误。
     */
    @SneakyThrows(Exception.class)
    public static byte[] htmlBytes2WordBytes(byte[] htmlBytes) {
        // 创建一个新的空文档
        Document doc = new Document();
        // 获取一个文档构建器，用于向文档插入内容
        DocumentBuilder builder = new DocumentBuilder(doc);
        // 将HTML字节序列转换为字符串并插入到文档中
        builder.insertHtml(new String(htmlBytes));
        // 创建一个输出流，用于存储转换后的DOCX文档
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // 将文档保存为DOCX格式，并写入到输出流中
        doc.save(outputStream, SaveFormat.DOCX);
        // 返回输出流的字节序列
        return outputStream.toByteArray();
    }


    /**
     * 将HTML字节序列转换为Word文档文件。
     * 该方法通过解析HTML字节序列，生成对应的Word文档。它利用Apache POI库来操作Microsoft Word文档。
     *
     * @param htmlBytes    包含HTML内容的字节序列。
     * @param wordFilePath Word文档的保存路径。此路径将用于创建并保存Word文档。
     * @return 返回一个File对象，代表已创建的Word文档文件。
     * @throws Exception 如果在解析HTML或保存Word文档过程中发生错误，则抛出异常。
     */
    @SneakyThrows(Exception.class)
    public static File htmlBytes2WordFile(byte[] htmlBytes, String wordFilePath) {
        // 创建一个新的文档对象
        Document doc = new Document();
        // 获取一个文档构建器，用于向文档中插入内容
        DocumentBuilder builder = new DocumentBuilder(doc);
        // 将HTML字节序列转换为字符串，并插入到文档中
        builder.insertHtml(new String(htmlBytes));
        // 保存文档到指定路径，格式为DOCX
        doc.save(wordFilePath, SaveFormat.DOCX);
        // 返回保存的Word文档的File对象
        return new File(wordFilePath);
    }


    /**
     * 将HTML字符串转换为Word文档。
     * 使用Apache POI库创建一个空的Word文档，并将HTML内容写入该文档。
     * 此方法假设HTML字符串是有效的，并且将直接将其内容写入Word文档，不进行任何格式转换或样式应用。
     *
     * @param html         要转换为Word文档的HTML字符串。
     * @param fileRootPath 存储生成的Word文档的文件夹路径。
     * @param wordFileName 生成的Word文档的文件名。
     * @return 生成的Word文档的完整文件路径。
     * @throws Exception 如果在文件操作或POI操作过程中发生错误。
     */
    @SneakyThrows(Exception.class)
    public static String html2Word(String html, String fileRootPath, String wordFileName) {
        // 构建Word文档的完整文件路径
        final String wordFilePath = fileRootPath + "/" + wordFileName;
        // 将HTML字符串转换为字节数组
        byte htmlBytes[] = html.getBytes();
        // 创建一个输入流，用于后续将HTML内容写入Word文档
        ByteArrayInputStream inputStream = new ByteArrayInputStream(htmlBytes);
        // 创建一个POIFSFileSystem对象，用于处理Word文档的存储结构
        POIFSFileSystem poifs = new POIFSFileSystem();
        // 获取根目录项
        DirectoryEntry directory = poifs.getRoot();
        // 在根目录下创建一个名为"WordDocument"的文档项，并将HTML内容写入其中
        DocumentEntry documentEntry = directory.createDocument("WordDocument", inputStream);
        // 创建一个输出流，用于将处理后的Word文档写入文件系统
        FileOutputStream outputStream = new FileOutputStream(wordFilePath);
        // 将POIFSFileSystem对象的内容写入输出流，从而创建Word文档
        poifs.writeFilesystem(outputStream);
        // 关闭输入流和输出流，释放资源
        inputStream.close();
        outputStream.close();
        // 返回生成的Word文档的完整路径
        return wordFilePath;
    }


}
